package com.flower.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.flower.domain.vo.buyer.ProductDetailVO;
import com.flower.domain.dto.buyer.product.ProductHotDto;
import com.flower.domain.dto.buyer.product.ProductQueryDto;
import com.flower.domain.entity.Product;
import com.flower.domain.entity.Review;
import com.flower.service.ProductService;
import com.flower.mapper.ProductMapper;
import com.flower.service.ReviewService;
import com.flower.service.ShopService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 86178
 * @description 针对表【product(商品详情表)】的数据库操作Service实现
 * @createDate 2025-03-04 12:26:59
 */
@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product>
        implements ProductService {

    private final ReviewService reviewService;
    private final ShopService shopService;

    @Override
    public Page<ProductDetailVO> pageList(ProductQueryDto queryDto) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();

        // 商品名称搜索
        if (StringUtils.hasText(queryDto.getProductName())) {
            wrapper.like(Product::getProductName, queryDto.getProductName());
        }

        // 分类过滤
        if (queryDto.getCategoryId() != null) {
            wrapper.eq(Product::getCategoryId, queryDto.getCategoryId());
        }

        // 店铺过滤
        if (queryDto.getShopId() != null) {
            wrapper.eq(Product::getShopId, queryDto.getShopId());
        }

        // 地区过滤
        if (StringUtils.hasText(queryDto.getRegion())) {
            wrapper.like(Product::getRegion, queryDto.getRegion());
        }

        // 价格区间过滤
        if (queryDto.getMinPrice() != null && queryDto.getMaxPrice() != null) {
            wrapper.between(Product::getPrice, queryDto.getMinPrice(), queryDto.getMaxPrice());
        } else if (queryDto.getMinPrice() != null) {
            wrapper.ge(Product::getPrice, queryDto.getMinPrice());
        } else if (queryDto.getMaxPrice() != null) {
            wrapper.le(Product::getPrice, queryDto.getMaxPrice());
        }

        // 库存状态过滤
        if (queryDto.getInStock() != null) {
            if (!queryDto.getInStock()) {
                wrapper.gt(Product::getStock, 0);
            } else {
                wrapper.le(Product::getStock, 0);
            }
        }

        // 排序处理
        String orderBy = queryDto.getOrderBy();
        if (orderBy != null) {
            switch (orderBy) {
                case "price_asc":
                    wrapper.orderByAsc(Product::getPrice);
                    break;
                case "price_desc":
                    wrapper.orderByDesc(Product::getPrice);
                    break;
                case "click_count_desc":
                    wrapper.orderByDesc(Product::getClickCount);
                    break;
                case "time_desc":
                    wrapper.orderByDesc(Product::getCreateTime);
                    break;
                case "comprehensive":
                case "default":
                default:
                    // 默认排序：先按点击量降序，再按创建时间降序
                    wrapper.orderByDesc(Product::getClickCount)
                           .orderByDesc(Product::getCreateTime);
                    break;
            }
        } else {
            // 未指定排序方式时的默认排序
            wrapper.orderByDesc(Product::getCreateTime);
        }

        Page<Product> page = new Page<>(queryDto.getPageNumber(), queryDto.getPageSize());

        Page<Product> originPage = page(page, wrapper);

        // 转换为分页对象
        Page<ProductDetailVO> resultPage = new Page<>();
        BeanUtils.copyProperties(originPage, resultPage); // 复制分页参数


        // 转换records并设置新属性
        List<ProductDetailVO> dtoList = originPage.getRecords().stream().map(product -> {
            ProductDetailVO dto = new ProductDetailVO();
            BeanUtils.copyProperties(product, dto);

            //使用lambda表达式从rewards中根据productId获取所有的rating
            // 获取该商品所有评分
            List<Integer> ratings = reviewService.lambdaQuery()
                    .eq(Review::getProductId, product.getProductId())
                    .list()
                    .stream()
                    .map(Review::getRating)
                    .toList();
            // 计算平均分（保留两位小数）
            Double average = ratings.isEmpty() ? 0.0 :
                    Math.round(ratings.stream().mapToInt(Integer::intValue).average().orElse(0.0) * 100) / 100.0;

            dto.setReviewCount(ratings.size());
            dto.setAverageRating(average);
            return dto;
        }).collect(Collectors.toList());

        resultPage.setRecords(dtoList);
        return resultPage;
    }

    @Override
    public ProductDetailVO getProductDetail(Integer id) {
        Product product = getById(id);
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }

        ProductDetailVO vo = new ProductDetailVO();
        BeanUtils.copyProperties(product, vo);
        vo.setShopName(shopService.getById(product.getShopId()).getShopName());
        // 获取该商品所有评分
        List<Integer> ratings = reviewService.lambdaQuery()
                .eq(Review::getProductId, product.getProductId())
                .list()
                .stream()
                .map(Review::getRating)
                .toList();
        // 计算平均分（保留两位小数）
        Double average = ratings.isEmpty() ? 0.0 :
                Math.round(ratings.stream().mapToInt(Integer::intValue).average().orElse(0.0) * 100) / 100.0;
        vo.setAverageRating(average);
        vo.setReviewCount(ratings.size());
        return vo;
    }

    @Override
    // 获取点击率前4的商品列表
    public List<ProductHotDto> getHotProductList() {
        List<Product> list = lambdaQuery()
                .orderByDesc(Product::getClickCount)
                .last("limit 4")
                .list();
        List<ProductHotDto> productHotDtoList = list.stream()
                .map(product -> {
                    ProductHotDto productHotDto = new ProductHotDto();
                    BeanUtils.copyProperties(product, productHotDto);
                    return productHotDto;
                })
                .toList();
        return productHotDtoList;
    }

    @Override
    public boolean updateClickCountById(Integer id) {
        Product product = this.getById(id);
        product.setClickCount(product.getClickCount() + 1);
        this.updateById(product);
        return true;
    }

    @Override
    public Page<ProductDetailVO> getShopProducts(ProductQueryDto queryDto) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        
        // 必须指定店铺ID
        if (queryDto.getShopId() == null) {
            throw new RuntimeException("店铺ID不能为空");
        }
        wrapper.eq(Product::getShopId, queryDto.getShopId());
        
        // 商品名称搜索
        if (StringUtils.hasText(queryDto.getProductName())) {
            wrapper.like(Product::getProductName, queryDto.getProductName());
        }
        
        // 分类过滤
        if (queryDto.getCategoryId() != null) {
            wrapper.eq(Product::getCategoryId, queryDto.getCategoryId());
        }
        
        // 地区过滤
        if (StringUtils.hasText(queryDto.getRegion())) {
            wrapper.like(Product::getRegion, queryDto.getRegion());
        }
        
        // 排序处理
        String orderBy = queryDto.getOrderBy();
        if (orderBy != null) {
            switch (orderBy) {
                case "price_asc":
                    wrapper.orderByAsc(Product::getPrice);
                    break;
                case "price_desc":
                    wrapper.orderByDesc(Product::getPrice);
                    break;
                case "click_count_desc":
                    wrapper.orderByDesc(Product::getClickCount);
                    break;
                case "time_desc":
                    wrapper.orderByDesc(Product::getCreateTime);
                    break;
                case "comprehensive":
                case "default":
                default:
                    // 默认排序：先按点击量降序，再按创建时间降序
                    wrapper.orderByDesc(Product::getClickCount)
                           .orderByDesc(Product::getCreateTime);
                    break;
            }
        } else {
            // 未指定排序方式时的默认排序
            wrapper.orderByDesc(Product::getCreateTime);
        }
        
        // 价格区间过滤
        if (queryDto.getMinPrice() != null && queryDto.getMaxPrice() != null) {
            wrapper.between(Product::getPrice, queryDto.getMinPrice(), queryDto.getMaxPrice());
        } else if (queryDto.getMinPrice() != null) {
            wrapper.ge(Product::getPrice, queryDto.getMinPrice());
        } else if (queryDto.getMaxPrice() != null) {
            wrapper.le(Product::getPrice, queryDto.getMaxPrice());
        }

        // 库存状态过滤
        if (queryDto.getInStock() != null) {
            if (!queryDto.getInStock()) {
                wrapper.gt(Product::getStock, 0);
            } else {
                wrapper.le(Product::getStock, 0);
            }
        }

        Page<Product> page = new Page<>(queryDto.getPageNumber(), queryDto.getPageSize());

        Page<Product> originPage = page(page, wrapper);

        // 转换为分页对象
        Page<ProductDetailVO> resultPage = new Page<>();
        BeanUtils.copyProperties(originPage, resultPage); // 复制分页参数


        // 转换records并设置新属性
        List<ProductDetailVO> dtoList = originPage.getRecords().stream().map(product -> {
            ProductDetailVO dto = new ProductDetailVO();
            BeanUtils.copyProperties(product, dto);

            //使用lambda表达式从rewards中根据productId获取所有的rating
            // 获取该商品所有评分
            List<Integer> ratings = reviewService.lambdaQuery()
                    .eq(Review::getProductId, product.getProductId())
                    .list()
                    .stream()
                    .map(Review::getRating)
                    .toList();
            // 计算平均分（保留两位小数）
            Double average = ratings.isEmpty() ? 0.0 :
                    Math.round(ratings.stream().mapToInt(Integer::intValue).average().orElse(0.0) * 100) / 100.0;

            dto.setReviewCount(ratings.size());
            dto.setAverageRating(average);
            return dto;
        }).collect(Collectors.toList());

        resultPage.setRecords(dtoList);
        return resultPage;
    }
}




